import { _decorator, AudioClip, Component, input, Input, instantiate, math, Node, Prefab } from 'cc';
import { GameManager } from './GameManager';
import { Enemy } from './Enemy';
import { AudioMgr } from './AudioMgr';
const { ccclass, property } = _decorator;

@ccclass('EnemyManager')
export class EnemyManager extends Component {

    private static instance:EnemyManager;

    @property
    enemy0SpawnRate:number = 1;
    @property(Prefab)
    enemy0Prefab:Prefab = null;

    @property
    enemy1SpawnRate:number = 2;
    @property(Prefab)
    enemy1Prefab:Prefab = null;

    @property
    enemy2SpawnRate:number = 3;
    @property(Prefab)
    enemy2Prefab:Prefab = null;

    @property
    rewardSpawnRate:number = 15;
    @property(Prefab)
    rewardTwoShootPrefab:Prefab = null;
    @property(Prefab)
    rewardBombPrefab:Prefab = null;

    doubleClickInterval:number = 0.4;
    lastClickTime:number = 0;
    @property([Node])
    enemyList:Node[] =  [];

    @property(AudioClip)
    useBombAudio:AudioClip = null;

    @property
    enemySpawnRate:number = 30;
    enemySpawnTimer:number = 0;

    @property
    enemy0SpawnRateThreshold:number = 0.3;
    @property
    enemy1SpawnRateThreshold:number = 4;
    @property
    enemy2SpawnRateThreshold:number = 10;

    public static getInstance():EnemyManager {
        return this.instance;
    }

    protected onLoad(): void {
        this.lastClickTime = 0;
        input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
    }

    start() {
        EnemyManager.instance = this;
        this.startEnemyStage1();
        this.schedule(this.rewardSpawn, this.rewardSpawnRate);
    }

    startEnemyStage1() {
        this.schedule(this.enemy0Spawn, this.enemy0SpawnRate);
        this.schedule(this.enemy1Spawn, this.enemy1SpawnRate);
        this.schedule(this.enemy2Spawn, this.enemy2SpawnRate);
    }

    startEnemyStage2() {
        this.schedule(this.enemy0Spawn, this.enemy0SpawnRate);
        this.schedule(this.enemy1Spawn, this.enemy1SpawnRate);
    }

    speedUpEnemySpawnRate() {
        if(this.enemy0SpawnRate > this.enemy0SpawnRateThreshold) {
            this.enemy0SpawnRate -= 0.05;
        }
        if(this.enemy1SpawnRate > this.enemy1SpawnRateThreshold) {
            this.enemy1SpawnRate -= 0.05;
        }
        if(this.enemy2SpawnRate > this.enemy2SpawnRateThreshold) {
            this.enemy2SpawnRate -= 0.05;
        }
    }

    update(deltaTime: number) {
        switch(GameManager.getInstance().getGameStage()) {
            case 1:
                this.updateEnemyStage1(deltaTime);
                break;
            case 2:
                this.updateEnemyStage2(deltaTime);
                break;
        }
    }

    // 更新阶段1敌人生成速率
    updateEnemyStage1(deltaTime: number) {
        this.enemySpawnTimer += deltaTime;
        if(this.enemySpawnTimer > this.enemySpawnRate) {
            this.enemySpawnTimer = 0;
            // 销毁敌人生成任务
            this.unDestroyEnemyStage1();
            this.speedUpEnemySpawnRate();
            this.startEnemyStage1();
        }
    }

    // 更新阶段2敌人生成速率
    updateEnemyStage2(deltaTime: number) {
        if(GameManager.getInstance().getStage2Switch()) {
            // 启动第二阶段的敌人生成逻辑
            this.unDestroyEnemyStage1();
            GameManager.getInstance().setStage2Switch(false);
            this.startEnemyStage2();
        }
    }

    unDestroyEnemyStage1() {
        this.unschedule(this.enemy0Spawn);
        this.unschedule(this.enemy1Spawn);
        this.unschedule(this.enemy2Spawn);
    }

    protected onDestroy(): void {
        this.unDestroyEnemyStage1();
        this.unschedule(this.rewardSpawn);
        input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
    }

    enemy0Spawn() {
        const enemyNode = this.spawn(this.enemy0Prefab, 0, -215, 215, 450);
        this.enemyList.push(enemyNode);
    }
    enemy1Spawn() {
        const enemyNode = this.spawn(this.enemy1Prefab, 1, -200, 200, 475);
        this.enemyList.push(enemyNode);
    }
    enemy2Spawn() {
        const enemyNode = this.spawn(this.enemy2Prefab, 2, -155, 155, 560);
        this.enemyList.push(enemyNode);
    }
    rewardSpawn() {
        const rewardRandom = math.randomRangeInt(0,2);
        let prefab = null;
        if(rewardRandom == 0) {
            prefab = this.rewardTwoShootPrefab;
        } else {
            prefab = this.rewardBombPrefab;
        }
        this.spawn(prefab, -1, -207, 207, 404);
    }

    spawn(enemyPrefab:Prefab, type:number, minX:number, maxX:number, Y:number):Node {
        const enemy = instantiate(enemyPrefab);
        let enemyComponet = enemy.getComponent(Enemy);
        if(enemyComponet) {
            enemyComponet.setType(type);
        }
        this.node.addChild(enemy);

        const randomX = math.randomRangeInt(minX, maxX);
        enemy.setPosition(randomX, Y);

        return enemy;
    }

    onTouchStart(event) {
        let currentTime = Date.now();
        let timeDiff = (currentTime - this.lastClickTime) / 1000;

        if(timeDiff < this.doubleClickInterval) {
            this.onDoubleClick(event);
        }
        this.lastClickTime = currentTime;
    }

    removeEnemy(n:Node) {
        const index = this.enemyList.indexOf(n);
        if(n) {
            this.enemyList.splice(index, 1);
        }
    }

    onDoubleClick(event) {
        if(!GameManager.getInstance().isHaveBomb()) {
            return;
        }

        AudioMgr.inst.playOneShot(this.useBombAudio, 0.4);
        GameManager.getInstance().useBomb();
        for(let enemy of this.enemyList) {
            enemy.getComponent(Enemy).killSelf();
        }
    }
}

